﻿#region

using System;
using System.Collections.ObjectModel;
using System.Windows.Browser;
using Radovici.SharedLibrary;
using Radovici.SharedLibrary.Javascript;

#endregion

namespace Radovici.Ctrls.Facebook
{
    public partial class FacebookApi
    {
        #region Nested type: FacebookUser

        [ScriptableType]
        public class FacebookUser : Notifiable
        {
            public const string DefaultUserId = "demo";
            public const string DefaultUserName = "demo";
            public static readonly FacebookUser DefaultUser = new FacebookUser(null, null);

            #region Private fields

            private readonly FacebookApi _api;
            private readonly ObservableCollection<FacebookUser> _friends = new ObservableCollection<FacebookUser>();
            private readonly string _uid;
            private string _music;
            private string _name;
            private string _picture;
            private string _profile;
            private string _timezone;

            #endregion

            public FacebookUser(FacebookApi api) : this(api, api.UserId)
            {
                ThreadHelper.UIContext.Post(delegate { LoadFriends(); }, null);
            }

            public FacebookUser(FacebookApi api, string uid)
            {
                if (api == null || string.IsNullOrEmpty(uid)) return;
                _api = api;
                _uid = uid;
                this.RegisterScriptableObject(ScriptableObjectId);
                LoadUser();
            }

            public string ScriptableObjectId
            {
                get { return string.Format("FacebookUser{0}", _uid); }
            }

            public string UserId
            {
                get { return string.IsNullOrEmpty(_uid) ? DefaultUserId : _uid; }
            }

            public string Name
            {
                get { return string.IsNullOrEmpty(_name) ? DefaultUserName : _name; }
            }

            public string Picture
            {
                get { return string.IsNullOrEmpty(_picture) ? "/RadoviciCtrls;component/Resources/blank.png" : _picture; }
            }

            public string Profile
            {
                get { return _profile; }
            }

            public string Music
            {
                get { return _music; }
            }

            public string Timezone
            {
                get { return _timezone; }
            }

            public ObservableCollection<FacebookUser> Friends
            {
                get { return _friends; }
            }

            #region LoadFriends javascript interop

            private void LoadFriends()
            {
                JavascriptInterop.Call(
                    string.Format(
                        @"
FB.Facebook.apiClient.fql_query('SELECT uid FROM user WHERE has_added_app = 1 and uid IN (SELECT uid2 FROM friend WHERE uid1 = {2}) ORDER BY first_name', 
    function(result, ex) {{ $get('{0}').Content.{1}.LoadFriendsCallback(result) }});",
                        _api.PluginId, ScriptableObjectId, _uid));
            }

            [ScriptableMember]
            public void LoadFriendsCallback(ScriptObject result)
            {
                if (result != null)
                {
                    int length = Convert.ToInt32(result.GetProperty("length"));
                    for (int i = 0; i < length; i++)
                    {
                        var item = result.GetProperty(i) as ScriptObject;
                        if (item != null)
                        {
                            object friendUid = item.GetProperty("uid");
                            if (friendUid != null)
                            {
                                AddFriend(friendUid.ToString());
                            }
                        }
                    }
                }
                Debug.WriteLine("FacebookUser.LoadFriendsCallback");
            }

            #endregion

            #region LoadUser javascript interop

            private void LoadUser()
            {
                if (!string.IsNullOrEmpty(_uid))
                {
                    JavascriptInterop.Call(
                        string.Format(
                            @"
    FB.Facebook.apiClient.users_getInfo
    (
        {2},
        'name,first_name,last_name,music,pic_square,timezone,profile_url',
        function(result) {{ $get('{0}').Content.{1}.LoadUserCallback(result[0]) }}
    );",
                            _api.PluginId, ScriptableObjectId, _uid));
                }
            }

            [ScriptableMember]
            public void LoadUserCallback(ScriptObject arr)
            {
                _name = arr.GetProperty("name") as string;
                _picture = arr.GetProperty("pic_square") as string;
                _profile = arr.GetProperty("profile_url") as string;
                _music = arr.GetProperty("music") as string;
                _timezone = arr.GetProperty("timezone") as string;
                Debug.WriteLine(string.Format("FacebookApi.GetUserCallback({0})", _uid));
                NotifyAll();
            }

            #endregion

            #region Private fields

            private void AddFriend(string uid)
            {
                _friends.Add(new FacebookUser(_api, uid));
                Notify("Friends");
            }

            private void NotifyAll()
            {
                Notify("UserId");
                Notify("Name");
                Notify("Picture");
                Notify("Profile");
                Notify("Music");
                Notify("Timezone");
                Notify("Friends");
            }

            #endregion
        }

        #endregion
    }
}